﻿using System;
using System.Linq;
using SManage.Infrastructure;
using System.Collections.Generic;
using System.Drawing;

namespace SManage.Control
{
    public static class TopologyExtension
    {
        public static ITopologyNode ToTopologyNode(this ITopologyInfo ti) {
            var tn = new TopologyNode();
            if (ti.Type == 6) {
                tn.Station = new Router();
            }

            if (ti.Type == 78) {
                tn.Station = new Switch();
            }

            if (ti.Type == 79) {
                tn.Station = new Computer();
            }
            tn.Station.Name = ti.Name;
            tn.Station.Description = ti.Description;

            foreach (var t in ti.InterfaceIPs) {
                tn.InterfaceList.Add(t.IP);
            }
            return tn;
        }

        public static ITopologyNode AssignLocation(this ITopologyNode current, Size size) {
            var n = current as TopologyNode;
            if (n != null) {
                n.Location = new Point(size.Width / 2, 30);
                var readyNodes = new List<ITopologyNode> { n };
                AssignPoint(n, 1, readyNodes);
            }
            return current;
        }

        private static void AssignPoint(ITopologyNode node, Int32 layer, IList<ITopologyNode> readyNodes) {
            var list = new List<ITopologyNode>();
            foreach (var l in node.LinkList) {
                if (readyNodes.Contains(l)) {
                    continue;
                }
                readyNodes.Add(l);
                list.Add(l);
            }
            if (list.Count() == 0) {
                return;
            }

            var n = node as TopologyNode;
            double rate = GetAdjustRate(layer + 1);
            double perDis = 200 * rate;
            if (n != null) {
                Int32 initX = n.Location.X - Convert.ToInt32((list.Count() - 1) * perDis / 2);
                for (int i = 0; i < list.Count(); i++) {
                    Int32 x = initX + Convert.ToInt32(perDis * i);
                    Int32 y = GetY(layer + 1);
                    ((TopologyNode)list[i]).Location = new Point(x, y);
                    AssignPoint(list[i], layer + 1, readyNodes);
                }
            }
        }

        private static Double GetAdjustRate(Int32 layer) {
            if (layer == 0) {
                return 0;
            }
            if (layer == 1) {
                return 1;
            }
            return GetAdjustRate(layer - 1) * 0.9;
        }

        private static Int32 GetY(Int32 layer) {
            if (layer == 0) {
                return 0;
            }

            if (layer == 1) {
                return 30;
            }

            return GetY(layer - 1) + 120 - 5 * layer;
        } 
    }
}
